package org.goldenmock.web.server;

import org.mortbay.jetty.Request;
import org.mortbay.jetty.handler.AbstractHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * The HttpRequestHandler basically maps HttpServletRequests into EasyRequests
 * and passes them on to the "delegate". The "delegate" then returns a
 * EasyHttpResponse, which is in turn translated to a HttpServletResponse and handed
 * over to jetty.
 *
 * @author Robin Wagenaar
 * @author Arjen van Staalduinen
 */
class HttpRequestHandler extends AbstractHandler {
    private final HttpServerInterface delegateHandler;

    public HttpRequestHandler(HttpServerInterface delegateHandler) {
        this.delegateHandler = delegateHandler;
    }

    /**
     * Calls the 'delegateHandler' (a.k.a. the mocked interface) with a EasyHttpRequest
     * (translated fields from HttpServletRequest).
     */
    @Override
    public void handle(String target, HttpServletRequest request, HttpServletResponse response, int dispatch) throws IOException, ServletException {
        if (request instanceof Request) {
            ((Request) request).setHandled(true);
            EasyHttpResponse easyHttpResponse = delegateHandler.handle(new EasyHttpRequest(request));
            mapResponse(response, easyHttpResponse);
        }
    }

    /**
     * Copies fields from EasyHttpResponse to the HttpServletResponse.
     */
    protected void mapResponse(HttpServletResponse response, EasyHttpResponse easyHttpResponse) throws IOException {
        EasyHttpResponse renderedEasyHttpResponse = easyHttpResponse.render();

        response.setContentType(renderedEasyHttpResponse.getContentType());
        response.setStatus(renderedEasyHttpResponse.getHttpCode());

        for (String key : renderedEasyHttpResponse.getHeaders().keySet()) {
            response.addHeader(key, renderedEasyHttpResponse.getHeaders().get(key));
        }

        response.getWriter().print(renderedEasyHttpResponse.getContent());
    }
}
